package com.wzcl.app.service.impl;

import com.wzcl.app.dao.model.*;
import com.wzcl.app.dao.repository.*;
import com.wzcl.app.model.common.RVO;
import com.wzcl.app.service.TopUpOrderService;
import com.wzcl.app.service.UserTopUpService;
import com.wzcl.app.utils.BeanUtil;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @author beingven
 * @Description 学币充值
 * @createTime 2020年11月20日 11:58:00
 */
@Service
public class UserTopUpServiceImpl implements UserTopUpService {
    @Resource
    private UserTopUpRepository userTopUpRepository;

    @Resource
    private RechargePriceListRepository rechargePriceListRepository;

    @Resource
    private UserCourseRepository userCourseRepository;

    @Resource
    private CourseRepository courseRepository;

    @Resource
    private AppUserRepository appUserRepository;

    @Resource
    private OrdersRepository ordersRepository;

    @Resource
    private CommodityRepository commodityRepository;

    @Resource
    private RefundRequestRepository refundRequestRepository;

    /**
     * 用户消费学币
     * @param orderNumber 订单号
     * @param money 订单总价
     * @param commodityIds 用户购买的商品id
     * @return 包含返回剩余学币信息的RVO
     */
    @Override
    public RVO userConsume(String orderNumber, Double money, List<Integer> commodityIds) {
        String phone = SecurityContextHolder.getContext().getAuthentication().getName();
        //通过电话找到用户id
        AppUser byPhone = appUserRepository.findByPhone(phone);
        // 通过用户电话查询用户对用的充值表记录
        UserTopUp user = userTopUpRepository.findAllByUserPhone(phone);
        if (user == null){
            // 没有充值记录
            RVO.error("该用户未充值");
        }
        //根据课程id集合去数据库中查询对应的课程并转换为UserCourse对象
        List<UserCourse> list = new ArrayList<>();
        for (int index = 0; index < commodityIds.size(); index++) {
            //根据商品id查询对应课程id
            Integer courseId = commodityRepository.findResourceIdById(commodityIds.get(index));
            //根据课程id查询对应的课程信息以便购买
            Course course = courseRepository.findAllByCourseId(courseId);
            UserCourse userCourse = BeanUtil.convertBean(course, UserCourse.class);
            userCourse.setUserPhone(phone);
            userCourse.setCourse(course);
            userCourse.setUserId(byPhone.getId());
            list.add(userCourse);
        }
        // 计算本次消费后剩余学币
        Double result = user.getLearnCoinSurplus() - money;
        if (result >= 0 ){
            //消费成功，添加所有课程到我的课程
            List<UserCourse> userCourses = userCourseRepository.saveAll(list);
            //更改课程订单状态为订单已完成
            ordersRepository.setPayStateAndOrdersStateByNo(1,3, orderNumber);
            if (userCourses.size() > 0){
                //更新用户冲值表信息
                userTopUpRepository.updateUserTopUpByUserPhone(result, phone);
                return RVO.success(result);
            }
        }
        return RVO.error("学币不足");
    }

    /**
     * 用户充值学币
     * @param productId 充值价格表productId
     * @return 包含返回剩余学币信息的RVO
     */
    @Override
    public RVO userTopUp(String productId) {
        String phone = SecurityContextHolder.getContext().getAuthentication().getName();
        //通过productId查询到对应的充值价目表，获取充值金额与充值学币
        RechargePriceList rechargePriceList = rechargePriceListRepository.findAllByProductId(productId);
        // 查询冲值表中是否有用户记录，没有就添加记录
        UserTopUp user = userTopUpRepository.findAllByUserPhone(phone);
        if (user == null){
            UserTopUp userTopUp = new UserTopUp();
            userTopUp.setLearnCoinSurplus(rechargePriceList.getStudyCoin());
            userTopUp.setTopUpMoney(rechargePriceList.getMoney());
            userTopUp.setUserPhone(phone);
            UserTopUp save = userTopUpRepository.save(userTopUp);
            return RVO.success(save.getLearnCoinSurplus());
        }
        // 如果有记录就做数据累加
        userTopUpRepository.updateUserTopUpByPhone(user.getLearnCoinSurplus() + rechargePriceList.getStudyCoin(), user.getTopUpMoney() + rechargePriceList.getMoney(), phone);
        return RVO.success(user.getLearnCoinSurplus() + rechargePriceList.getStudyCoin());
    }

    /**
     * 查询当前用户学币
     * @return 包含返回学币信息的RVO
     */
    @Override
    public RVO findAllByUserPhone() {
        String phone = SecurityContextHolder.getContext().getAuthentication().getName();
        UserTopUp allByUserPhone = userTopUpRepository.findAllByUserPhone(phone);
        if (allByUserPhone == null){
            return RVO.success("该用户未充值");
        }
        return RVO.success(allByUserPhone.getLearnCoinSurplus());
    }

    /**
     * 申请课程退款
     * @param orderNumber 退款订单号
     * @param returnReason 退款原因
     * @return 返回剩余学币
     */
    @Override
    public RVO applyReturnLearnCoin(String orderNumber, String returnReason) {
        // 更新订单为正在退款
        ordersRepository.updateStateByOrderNumber(3, orderNumber);
        String phone = SecurityContextHolder.getContext().getAuthentication().getName();
        Double learnCoin = userTopUpRepository.findLearnCoinByUserPhone(phone);
        // 添加退款信息
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setOrderNo(orderNumber);
        refundRequest.setReason(returnReason);
        refundRequest.setCreateTime(new Date(System.currentTimeMillis()));
        //退款进度为待审核
        refundRequest.setAuditState(0);
        refundRequestRepository.save(refundRequest);
        // 更新订单信息
        return RVO.success();
    }

    /**
     * 课程退款（返回用户学币删除用户课程）
     * @param orderNumber 退款订单号
     * @param result 申请退款结果（1同意退款, 2拒绝退款）
     * @param refusedReason 拒绝退款理由
     * @return 返回剩余学币
     */
    @Override
    public RVO returnLearnCoin(String orderNumber, Integer result, String refusedReason) {
        if (result == 2){
            //退款失败重新变为已支付
            ordersRepository.updateStateByOrderNumber(1, orderNumber);
            // 更新退款表
            refundRequestRepository.updateAuditStateByOrderNumber(2, refusedReason, orderNumber);
            return RVO.success("退款申请已拒绝");
        }
        //通过订单号查询电话号码
        String phone = ordersRepository.findAllByOrderNumber(orderNumber).getUserPhone();
        // 查询退款金额
        BigDecimal payMoney = ordersRepository.findAllByOrderNumber(orderNumber).getPayMoney();
        // 查询用户剩余学习币
        Double learnCoin = userTopUpRepository.findLearnCoinByUserPhone(phone);
        //退款后用户的总学币
        learnCoin = learnCoin + payMoney.doubleValue();
        // 更新用户学习币信息
        userTopUpRepository.updateUserTopUpByUserPhone(learnCoin, phone);
        // 更新退款表为审核通过
        refundRequestRepository.updateAuditStateByOrderNumber(1, null, orderNumber);
        //更新订单信息
        ordersRepository.updateStateByOrderNumber(4, orderNumber);
        // 根据订单号查询订单详情
        List<OrderDetail> details = ordersRepository.findAllByOrderNumber(orderNumber).getDetails();
        // 根据订单详情拿到对应的课程
        for (int index = 0; index < details.size(); index++) {
            //通过商品id拿到课程id
            Integer resourceId = commodityRepository.findResourceIdById(details.get(index).getCommodity().getId());
            // 删除用户的课程
            userCourseRepository.deleteByCourseAndPhone(resourceId, phone);
        }
        return RVO.success("退款成功");
    }
}
